<?php

namespace App\Http\Traits\Auth;

use Laravel\Socialite\Facades\Socialite;
use Laravel\Socialite\Contracts\User as SocialiteUser;
use Illuminate\Http\Exceptions\HttpResponseException;

trait SocialiteTrait
{
    /**
     * 返回第三方登录实例
     *
     * @param $type
     *
     * @return \Laravel\Socialite\Two\ProviderInterface
     */
    protected function socialite($type)
    {
        try {

            $socialite = Socialite::driver($type);

        } catch (\InvalidArgumentException $exception) {

            // 不支持的第三方登录
            abort(404, $exception->getMessage());
        }

        return $socialite;
    }

    /**
     * 存储第三方登录数据
     *
     * @param $type
     * @param SocialiteUser $user
     */
    protected function storeSocialite($type, SocialiteUser $user)
    {
        session()->put('socialite', [
            'type' => $type,
            'user' => $user
        ]);
    }

    /**
     * 清除第三方登录数据
     *
     * @return \Illuminate\Session\Store
     */
    protected function forgetSocialite()
    {
        return session()->forget('socialite');
    }

    /**
     * 是否已有第三方登录数据
     *
     * @return bool
     */
    protected function hasSocialite()
    {
        return session()->has('socialite.user');
    }

    /**
     * 获取第三方登录数据
     *
     * @return SocialiteUser
     */
    protected function getSocialite()
    {
        return session('socialite.user');
    }

    /**
     * 获取登录类型
     *
     * @return \Illuminate\Session\SessionManager|\Illuminate\Session\Store|mixed
     */
    protected function getSocialiteType()
    {
        return session('socialite.type');
    }

    /**
     * 获取第三方登录数据,如果没有,则抛出异常
     *
     * @return SocialiteUser
     */
    protected function getSocialiteOrFail()
    {
        if (!$this->hasSocialite()) {
            $this->responseSocialiteExpired();
        }

        return $this->getSocialite();
    }

    /**
     * 登录状态过期
     *
     * @throws HttpResponseException
     */
    protected function responseSocialiteExpired()
    {
        throw new HttpResponseException(redirect()->route('login')->withErrors([
            'login' => ['登录状态已过期, 请重新登录']
        ]));
    }

    /**
     * 获取第三方登录的账号绑定数据
     *
     * @return array
     */
    protected function getSocialiteData()
    {
        $socialite = $this->getSocialiteOrFail();

        return [
            'type' => $this->getSocialiteType(),
            'open_id' => $socialite->getId(),
            'access_token' => $socialite->token,
            'access_token_expires' => now()->addSeconds($socialite->expiresIn),
            'refresh_token' => $socialite->refreshToken
        ];
    }
}